/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package structures.table;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import structures.table.action.Action;
import structures.table.symboltable.ItemInfo;

/**
 *
 * @author Slayer
 */
public class LRTable {

    private final HashMap<ItemInfo, ArrayList<Action>> table;
    private final int size;

    public LRTable(int capacity) {
        table = new HashMap<ItemInfo, ArrayList<Action>>();
        size = capacity;
    }

    public int getStateAmount() {
        return size;
    }

    private ArrayList<Action> generateList() {
        ArrayList<Action> list = new ArrayList<Action>(size);

        for (int index = 0; index < size; ++index) {
            list.add(null);
        }

        return list;
    }

    public void put(int state, ItemInfo symbol, Action action) {
        if (!table.containsKey(symbol)) {
            ArrayList<Action> list = generateList();

            list.set(state, action);
            table.put(symbol, list);
        } else {
            table.get(symbol).set(state, action);
        }
    }

    public Action get(int state, ItemInfo symbol) {
        if (!table.containsKey(symbol)) {
            throw new IllegalStateException("Can't find " + symbol.toString() + " in table.");
        } else {
            return table.get(symbol).get(state);
        }
    }
    
    public List<Action> getColumn(ItemInfo item) {
    	return table.get(item);
    }
    
    public List<ItemInfo> getColumns() {
    	return new ArrayList<ItemInfo>(table.keySet());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final LRTable other = (LRTable) obj;
        if (table.size() != other.table.size()) {
            return false;
        }

        if (!table.keySet().equals(other.table.keySet())) {
            return false;
        }

        Iterator<ItemInfo> it = table.keySet().iterator();

        while (it.hasNext()) {
            ItemInfo item = it.next();

            if (!table.get(item).equals(other.table.get(item))) {
                return false;
            }
        }

        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 43 * hash + (this.table != null ? this.table.hashCode() : 0);
        hash = 43 * hash + this.size;
        return hash;
    }
}
